import { InboxOutlined } from "@ant-design/icons";

import { Button, message, Progress } from "antd";

import "./FileUploader.css";
import React, { useCallback, useRef, useState } from "react";

import useDrag from "./useDrag";

import { CHUNK_SIZE } from "./constant";
import axios from "../http/axios";
import axiosInstance from "./axiosInstance";

import { Cell, Switch } from "react-vant";

import { Qr, CreditPay, Lock } from "@react-vant/icons";
import storage from "../utils/storage";



function FileUploader() {
  const uploadContainerRef = useRef(null);
  const { selectedFile, filePreview, resetFileStatus } =
    useDrag(uploadContainerRef);
  let [uploadProgress, setUploadProgress] = useState({});
  const selfinfo = storage.get("selfinfo");
  const user_id = sessionStorage.getItem("user_id");
  console.log(user_id);
  const [inputText, setInputText] = useState("");
  const [title, setTiele] = useState('')
  // const [maxCharacters, setMaxCharacters] = useState(50);

  // const handleInputChange = (event) => {
  //   const text = event.target.value;
  //   setInputText(text);

  //   const counter = document.getElementById("counter");
  //   if (counter) {
  //     counter.textContent = `${text.length}/${maxCharacters}`;
  //   }

  //   if (text.length > maxCharacters) {
  //     event.target.value = text.slice(0, maxCharacters);
  //     setInputText(text.slice(0, maxCharacters));
  //     if (counter) {
  //       counter.textContent = `${maxCharacters}/${maxCharacters}`;
  //     }
  //   }
  // };

  const resetAllStatus = () => {
    resetFileStatus();
    setUploadProgress({});
  };
  const handleUpload = async () => {
    if (!selectedFile) {
      message.error("你尚未选中任何文件");
      return;
    }
    const filename = await getFileName(selectedFile);

    console.log('https://www.pabzibo.live:3001/upload/' + filename);
    // //添加到数据库
    let res = await axios.post('upinfo', { filename: 'https://www.pabzibo.live:3001/upload/' + filename, _id: user_id, title });
    //上传文件
    await uploadFile(selectedFile, filename, setUploadProgress, resetAllStatus);
  };
  const renderButton = () => {
    return (
      <Button
        onClick={handleUpload}
        style={{
          left: "16px",
          top: "180px",
          width: "343px",
          height: "44px",
          lineHeight: "20px",
          borderRadius: "30px 30px 30px 30px",
          backgroundColor: "rgba(247,221,94,1)",
          color: "rgba(244, 210, 105, 1)",
          fontSize: "14px",
          textAlign: "center",
          fontFamily: "Roboto",
        }}
      >
        <span
          style={{
            left: "152px",
            top: "567px",
            width: "72px",
            height: "25px",
            lineHeight: "25px",
            color: "rgb(16,16,16)",
            fontSize: "18px",
            textAlign: "left",
            fontFamily: "PingFangSC-regular",
          }}
        >
          发布作品
        </span>
      </Button>
    );
  };
  const renderProgress = () => {
    return Object.keys(uploadProgress).map((chunkName, index) => (
      <div>
        <span style={{ fontSize: "14px" }}>切片{index}:</span>
        <Progress percent={uploadProgress[chunkName]} />
      </div>
    ));
  };

  const renderTotalProgress = () => {
    const percents = Object.values(uploadProgress);
    const totalPercent = Math.round(
      percents.reduce((acc, curr) => acc + curr, 0) / percents.length
    );
    return (
      <div style={{ marginTop: "10px" }}>
        <span style={{ fontSize: "14px" }}>上传总进度：</span>
        <Progress percent={totalPercent} />
      </div>
    );
  };



  return (
    <>
      <div className="upload-container" ref={uploadContainerRef}>
        {/* <InboxOutlined /> */}
        {renderFilePreview(filePreview)}
      </div>
      <div>
        <>
          <Cell
            icon={
              <span
                style={{
                  left: "17px",
                  top: "295px",
                  width: "18px",
                  height: "20px",
                  backgroundColor: "rgba(255,255,255,1)",
                }}
              >
                <Qr />
              </span>
            }
            style={{
              left: "0px",
              top: "24px",
              width: "375px",
              height: "55px",
              lineHeight: "20px",
              backgroundColor: "rgba(255,255,255,1)",
              color: "rgba(16,16,16,1)",
              fontSize: "14px",
              textAlign: "center",
              fontFamily: "Roboto",
            }}
            title={
              <span
                style={{
                  left: "43px",
                  top: "60px",
                  width: "34px",
                  height: "24px",
                  lineHeight: "24px",
                  color: "rgba(51,51,51,1)",
                  fontSize: "17px",
                  textAlign: "left",
                  fontFamily: "PingFangSC-regular",
                }}
              >
                分类
              </span>
            }
            value={<span></span>}
            isLink
          />
          <Cell
            icon={
              <span
                style={{
                  left: "16px",
                  top: "351px",
                  width: "19px",
                  height: "18px",
                  backgroundColor: "rgba(255,255,255,1)",
                }}
              >
                <CreditPay />
              </span>
            }
            style={{
              left: "0px",
              top: "30px",
              width: "375px",
              height: "55px",
              lineHeight: "20px",
              backgroundColor: "rgba(255,255,255,1)",
              color: "rgba(16,16,16,1)",
              fontSize: "14px",
              textAlign: "center",
              fontFamily: "Roboto",
            }}
            title={
              <span
                style={{
                  left: "43px",
                  top: "88px",
                  width: "85px",
                  height: "24px",
                  lineHeight: "24px",
                  color: "rgb(51,51,51)",
                  fontSize: "17px",
                  textAlign: "left",
                  fontFamily: "PingFangSC-regular",
                }}
              >
                添加到合集
              </span>
            }
            isLink
            value={<span></span>}
          />
          <Cell
            icon={
              <span
                style={{
                  left: "18px",
                  top: "405px",
                  width: "16px",
                  height: "19px",
                  backgroundColor: "rgba(255,255,255,1)",
                }}
              >
                <Lock />
              </span>
            }
            style={{
              left: "0px",
              top: "36px",
              width: "375px",
              height: "55px",
              lineHeight: "20px",
              backgroundColor: "rgba(255,255,255,1)",
              color: "rgba(16,16,16,1)",
              fontSize: "14px",
              textAlign: "center",
              fontFamily: "Roboto",
            }}
            title={
              <span
                style={{
                  left: "43px",
                  top: "114px",
                  width: "85px",
                  height: "24px",
                  lineHeight: "24px",
                  color: "rgb(51,51,51)",
                  fontSize: "17px",
                  textAlign: "left",
                  fontFamily: "PingFangSC-regular",
                }}
              >
                所有人可见
              </span>
            }
            value={<Switch size="28px" defaultChecked />}
          />
        </>
      </div>
      {renderButton()}
      {renderTotalProgress()}
      {renderProgress()}
    </>
  );
}
function createRequest(filename, chunkFileName, chunk, setUploadProgress) {
  return axiosInstance.post(`/upload/${filename}`, chunk, {
    headers: {
      //这个请求头是告诉服务器请求体是一个二进制格式，是一个字节流
      "Content-Type": "application/octet-stream",
    },
    params: {
      //此查询参数会拼接到url地址里
      chunkFileName,
    },
    //axios内部调用原生的XMLHttpRequest，XMLHttpRequest有一个事件onprogress

    onUploadProgress: (progressEvent) => {
      //上传进度发生变化的事件回调函数
      //用已经上传的字节数除以总字节数得到完成的百分比，这是一个0-1小数，乘以100变成一个0到100的整数
      const percentCompleted = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      setUploadProgress((prevProgress) => ({
        ...prevProgress,
        [chunkFileName]: percentCompleted,
      }));
    },
  });
}
/**
 * 实现切片上传大文件
 * @param {*} file 大文件
 * @param {*} filename 文件名
 */
async function uploadFile(file, filename, setUploadProgress, resetAllStatus) {
  const { needUpload } = await axiosInstance.get(`/verify/${filename}`);
  if (!needUpload) {
    message.success("文件已存在，秒传成功");
    return resetAllStatus();
  }
  //把大文件进行切片
  const chunks = createFileChunks(file, filename);

  //实现并行上传
  const requests = chunks.map(({ chunk, chunkFileName }) => {
    return createRequest(filename, chunkFileName, chunk, setUploadProgress);
  });
  try {
    //并行上传每个分片
    await Promise.all(requests);
    //等全部的分片上传完了，会向服务器发送一个合并文件的请求
    await axiosInstance.get(`/merge/${filename}`);
    message.success("文件上传完成");
    resetAllStatus();
  } catch (error) {

    message.error("上传出错");
  }
}

function createFileChunks(file, filename) {
  //最后切成的分片的数组
  let chunks = [];
  //计算一共要切成多少片
  let count = Math.ceil(file.size / CHUNK_SIZE);
  for (let i = 0; i < count; i++) {
    let chunk = file.slice(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE);
    chunks.push({
      chunk,
      chunkFileName: `${filename}-${i}`,
    });
  }
  return chunks;
}

/**
 * 根据文件对象获取根据文件内容得到的hash文件名
 * @param {*} file 文件对象
 */

async function getFileName(file) {
  //计算此文件的hash值
  const fileHash = await calculateFileHash(file);
  //获取文件扩展名
  const fileExtension = file.name.split(".").pop();
  return `${fileHash}.${fileExtension}`;
}

/**
 * 计算文件的hash字符串
 * @param {*} file
 * @returns
 */

async function calculateFileHash(file) {
  const arrayBuffer = await file.arrayBuffer();
  const hashBuffer = await crypto.subtle.digest("SHA-256", arrayBuffer);
  return bufferToHex(hashBuffer);
}

/**
 * 把ArrayBuffer转成16进制的字符串
 * @param {*} buffer
 * @returns
 */

function bufferToHex(buffer) {
  return Array.from(new Uint8Array(buffer))
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
}

/**
 * 显示文件的预览
 * @param {*} filePreview
 */

function renderFilePreview(filePreview) {
  const { url, type } = filePreview;
  if (url) {
    if (type.startsWith("video/")) {
      return <video src={url} alt="preview" controls />;
    } else if (type.startsWith("image/")) {
      return <img src={url} alt="preview" />;
    } else {
      return url;
    }
  } else {
    return (
      <div style={{ display: "flex", justifyContent: "space-between", marginTop: "24px" }}>
        <div style={{ width: "110px", height: "114px" }}>
          <p>
            <InboxOutlined
              style={{
                marginLeft: "0px",
                paddingLeft: "25px",
                boxSizing: "border-box",
                marginTop: "-10px",
                width: "110px",
                height: "90px",
                lineHeight: "144px",
                textAlign: "center",
                borderRadius: "6px 6px 6px 6px",
                backgroundColor: "rgba(255,255,255,1)",
              }}
            />
          </p>
          <p>
            <input
              style={{
                marginLeft: "0px",
                marginTop: "10px",
                width: "110px",
                height: "24px",
                lineHeight: "20px",
                borderRadius: "0px 0px 6px 6px",
                backgroundColor: "rgba(0,0,0,1)",
                color: "rgba(255,255,255,1)",
                fontSize: "14px",
                textAlign: "center",
                fontFamily: "Roboto",
              }}
              type="text"
              value={url}
              placeholder="选封面"
            />
          </p>
        </div>
        <div>
          <textarea

            id="aaaa"
            // maxLength={maxCharacters}
            style={{
              border: "none",
              width: "180px",
              height: "110px",
              marginLeft: "35px",
              marginTop: "2px",
              fontSize: "14px",
            }}
            type="text"
            placeholder="给视频取个标题吧~"
          />
          <p style={{ fontSize: "14px", color: "rgba(16,16,16,1)", marginLeft: "190px", marginTop: "0" }}>0/50</p>
          {/* <div id="counter">0/{maxCharacters}</div> */}
        </div>
      </div>
    );
  }
}

export default FileUploader;
